//  This file is part of NHibernate.ReLinq.Sample a sample showing
//  the use of the open source re-linq library to implement a non-trivial 
//  Linq-provider, on the example of NHibernate (www.nhibernate.org).
//  Copyright (C) 2005-2009 rubicon informationstechnologie gmbh, www.rubicon.eu
//  
//  NHibernate.ReLinq.Sample is based on re-motion re-linq (http://www.re-motion.org/).
//  
//  NHibernate.ReLinq.Sample is free software; you can redistribute it 
//  and/or modify it under the terms of the MIT License 
// (http://www.opensource.org/licenses/mit-license.php).
// 
using System.Collections.Generic;
using System.Linq;
using Remotion.Linq;
using ScrappyDB.Linq.SdbQueryGeneration;
using ScrappyDB;
using ScrappyDB.BaseClasses;

namespace ScrappyDB.Linq
{
  // Called by re-linq when a query is to be executed.
    public class SdbQueryExecutor : IQueryExecutor 
  {
    public SdbQueryExecutor ()
    {
    }

    // Executes a query with a scalar result, i.e. a query that ends with a result operator such as Count, Sum, or Average.
    public int ExecuteScalar<T>(QueryModel queryModel)
    {
        var db = new Db();

        var commandData = HqlGeneratorQueryModelVisitor<T>.GenerateHqlQuery(queryModel);
        var query = commandData.CreateQuery();

        //TODO: for now these are all "CONSISTENT", but we should figure out a way to make this configurable...
        var result = db.CountRawSql(query, null, true);
        return result;
    }

    // Executes a query with a single result object, i.e. a query that ends with a result operator such as First, Last, Single, Min, or Max.
        public T ExecuteSingle<T>(QueryModel queryModel, bool returnDefaultWhenEmpty) where T : class, new()
    {
      return returnDefaultWhenEmpty ? ExecuteCollection<T> (queryModel).SingleOrDefault () : ExecuteCollection<T> (queryModel).Single ();
    }

    // Executes a query with a collection result.
    public IEnumerable<T> ExecuteCollection<T>(QueryModel queryModel) where T : class, new()
    {
        var db = new Db();

      var commandData = HqlGeneratorQueryModelVisitor<T>.GenerateHqlQuery(queryModel);
      var query = commandData.CreateQuery ();

      //TODO: for now these are all "CONSISTENT", but we should figure out a way to make this configurable...
      var result = db.Query<T>(query, true);
      return result;
    }
  }
}